library(tidyverse)
library(biomaRt)
library(ggrepel)
library(clusterProfiler)
library(enrichplot)
# Parallel
library(BiocParallel)
register(MulticoreParam(6))

load('../data/microarray_NGS_objects.Rdata')
load('../data/top_tables.Rdata')
sva_counts <- read_tsv('../data/sva_counts.tsv.gz')
Rows: 14318 Columns: 66
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr  (1): Gene
dbl (65): GSM2944692, GSM2944693, GSM2944694, GSM2944695, GSM2944696, GSM2944697, GSM2944698, GSM2944699, GSM2944700,...

β„Ή Use `spec()` to retrieve the full column specification for this data.
β„Ή Specify the column types or set `show_col_types = FALSE` to quiet this message.
sample_meta_D <- sample_meta %>% filter(Sample %in% colnames(sva_counts)) %>%
  dplyr::select(Sample:Section, Layout:Fusion) %>%
  mutate(S2 = case_when(Section == 'OF' ~ 'OF', TRUE ~ 'OC')) %>%
  unique()

box_maker <- function(table, genes, section = c('OF','OC'), type = 'temporal'){
  if ('matrix' %in% class(table)){
    table <- table %>%
      as_tibble(rownames = 'Gene')
  }
  if (type == 'temporal'){
    plot <- table %>% 
      pivot_longer(-Gene, names_to = 'Sample', values_to = 'Expression') %>%
      mutate(Sample = gsub('_.*|.CEL.*','',Sample)) %>%
      left_join(sample_meta_D) %>%
      mutate(S2 = case_when(Section == 'OF' ~ 'OF',TRUE ~ 'OC')) %>%
      filter(Gene %in% genes, S2 %in% section) %>%
      #filter(Gene %in% row.names(top.table_OF_AD %>% head(10))) %>%
      mutate(Fusion = factor(Fusion, levels = c('Before','During','After'))) %>%
      mutate(OrgTech = paste(Organism, Technology, sep = '_')) %>% 
      ggplot(aes(x=Fusion, y=Expression, color = Organism, shape = Technology)) +
      # geom_boxplot(aes(group = Fusion), color = 'Black', outlier.colour = NA) +
      # geom_boxplot(aes(group = interaction(Organism,Fusion)), outlier.colour = NA) +
      ggbeeswarm::geom_quasirandom(size = 3, alpha = 0.7) +
      cowplot::theme_cowplot() +
      facet_grid(~Gene + S2, scales = 'free_y') +
      ggsci::scale_color_aaas() +
      ylab('log2 (corrected counts)') +
      stat_summary(fun=mean, geom = 'line', aes(group = OrgTech, color = Organism)) }
  else {
    plot <- table %>% 
      pivot_longer(-Gene, names_to = 'Sample', values_to = 'Expression') %>%
      mutate(Sample = gsub('_.*|.CEL.*','',Sample)) %>%
      left_join(sample_meta_D) %>%
      mutate(S2 = case_when(Section == 'OF' ~ 'OF',TRUE ~ 'OC')) %>%
      filter(Gene %in% genes, S2 %in% section) %>%
      mutate(Fusion = factor(Fusion, levels = c('Before','During','After'))) %>%
      filter(Fusion == 'During') %>% 
      mutate(OrgTech = paste(Organism, Technology, sep = '_')) %>% 
      ggplot(aes(x=S2, y=Expression, color = Organism, shape = Technology)) +
      # geom_boxplot(aes(group = Fusion), color = 'Black', outlier.colour = NA) +
      # geom_boxplot(aes(group = interaction(Organism,Fusion)), outlier.colour = NA) +
      ggbeeswarm::geom_quasirandom(size = 3, alpha = 0.7) +
      cowplot::theme_cowplot() +
      ggsci::scale_color_aaas() +
      ylab('log2 (corrected counts)') +
      xlab('Section') +
      stat_summary(fun=mean, geom = 'line', aes(group = OrgTech, color = Organism)) + facet_wrap(~Gene)
  }
  plot
}

volcano_maker <- function(df, 
                          title="Volcano Plot", 
                          pvalue='P.Value', 
                          padj='adj.P.Val', 
                          logFC='logFC', 
                          gene_list = ''){
  df$pvalue <- df[,pvalue]
  df$log2FoldChange <- df[,logFC]
  df$padj <- df[,padj]
  df$Gene <- row.names(df)
  df <- df[!is.na(df$pvalue),]
  print(dim(df))
  
  df <- df %>% mutate(Class = case_when(padj < 0.05 & abs(logFC) > 1~ "FDR < 0.05 & logFC > 1",
                                        padj < 0.1 & abs(logFC) > 1 ~ 'FDR < 0.1 & logFC > 1',
                                        TRUE ~ 'Not significant'))
  df$GeneT <- df$Gene
  if (gene_list == ''){
    gene_list <- df %>% filter(padj < 0.05) %>% pull(Gene) %>% head(10)
  }
  df$Gene[!df$Gene %in% gene_list] <- ''
  
  plot <- ggplot(data=df,aes(label=Gene, x = log2FoldChange, y = -log10(pvalue))) +
    geom_point(aes(colour=Class)) +
    scale_colour_manual(values=c("darkred", "red", "grey")) +
    cowplot::theme_cowplot() +
    geom_vline(aes(xintercept=-1),linetype="dotted") +
    geom_vline(aes(xintercept=1),linetype="dotted") +
    geom_vline(aes(xintercept=-2),linetype="dotted") +
    geom_vline(aes(xintercept=2),linetype="dotted") +
    geom_label_repel(max.overlaps = 100) +
    xlab('logFC') + ylab('-log10(p value)') +
    ggtitle(title) + cowplot::theme_cowplot()
  
  plot
}

During vs After (OF)

2021-12-13

Positive means higher expression in the After relative to the During time point (among OF samples only)

Volcano

volcano_maker(top.table_OF_AD, title = 'OF: During vs After',
              
              gene_list = c(top.table_OF_AD %>% filter(logFC > 0) %>% head(12) %>% row.names(),
                            top.table_OF_AD %>% filter(logFC < 0) %>% head(12) %>% row.names()))
[1] 14318    10
Warning in if (gene_list == "") { :
  the condition has length > 1 and only the first element will be used

Diff Table

Genes with an FDR < 0.1 in this test.

top.table_OF_AD %>% as_tibble(rownames = 'Gene') %>% filter(adj.P.Val < 0.1) %>%  DT::datatable()

Expression of top 6 genes (by FDR) across section and stage

Colored by organism. Each line is drawn for organism / technology (remember, mouse has both microarray and RNA-seq).

Up (genes that go up in expression During -> After)

box_maker(sva_counts, 
          genes = top.table_OF_AD %>% 
            as_tibble(rownames = 'Gene') %>% 
            filter(adj.P.Val < 0.05, logFC > 0) %>% head(10) %>% pull(Gene),
          section = c('OF'), type = 'temporal')
Joining, by = "Sample"

Down

box_maker(sva_counts, 
          genes = top.table_OF_AD %>% 
            as_tibble(rownames = 'Gene') %>% 
            filter(adj.P.Val < 0.05, logFC < 0) %>% head(10) %>% pull(Gene),
          section = c('OF'), type = 'temporal')
Joining, by = "Sample"

Enrichment Analysis (GO, GSEA)

GSEA

GSEA uses a ranked list of genes by logFC. So the p values are not used in this situation. The order is. So the GSEA is useful in situations where there are very few differentially expressed genes.

Activated terms (higher in the β€œAfter”) relate to ion channels and cell adhesion. Suppressed terms (genes higher expressed in the During) relate to cell cycle and metabolism.

Dotplot

all_genes <- bitr(top.table_OF_AD %>% as_tibble(rownames = 'Gene') %>% filter(!grepl('RPS|RPL', Gene)) %>% pull(Gene), fromType="SYMBOL", toType="ENTREZID", OrgDb="org.Hs.eg.db")
'select()' returned 1:many mapping between keys and columns
Warning in bitr(top.table_OF_AD %>% as_tibble(rownames = "Gene") %>% filter(!grepl("RPS|RPL",  :
  0.01% of input gene IDs are fail to map...
all_genes <- all_genes %>% left_join(top.table_OF_AD %>% as_tibble(rownames = 'SYMBOL'), by = c('SYMBOL'))

logFC <- all_genes$logFC
names(logFC) <- all_genes$ENTREZID
logFC <- na.omit(logFC)

logFC = sort(logFC, decreasing = TRUE)

gse <- gseGO(geneList=logFC,
             ont ="ALL",
             keyType = "ENTREZID",
             pvalueCutoff = 0.05,
             OrgDb = org.Hs.eg.db,
             pAdjustMethod = "BH",
             eps = 0)
preparing geneSet collections...
GSEA analysis...
Warning in preparePathwaysAndStats(pathways, stats, minSize, maxSize, gseaParam,  :
  There are ties in the preranked stats (0.09% of the list).
The order of those tied genes will be arbitrary, which may produce unexpected results.
leading edge analysis...
done...
gse <- setReadable(gse, OrgDb = org.Hs.eg.db)
# change sort logic
gseF <- gse
gseF@result <- rbind(gseF@result %>% arrange(NES) %>% head(20),
                     gseF@result %>% arrange(NES) %>% tail(20) %>% arrange(-NES)
)
dotplot(gse, showCategory=15, split=".sign") + facet_grid(.~.sign) + cowplot::theme_cowplot()

Table

So you can see the genes in the ontology term. The genes get β€œincluded” as enriched if GSEA deems them to be ranked unusually high.

gse@result %>% as_tibble() %>% arrange(-abs(NES)) %>% filter(p.adjust < 0.05) %>%  DT::datatable()

GO Enrichment

GO enrichment uses a cutoff between differentially expressed genes (FDR < 0.1 in this case) and everything else.

Loads of stuff relating to visual function and development.


diff_genes <- top.table_OF_AD %>% as_tibble(rownames = 'Gene') %>% filter(adj.P.Val < 0.1, !grepl('RPL|RPS', Gene)) 
eg_diff_genes <- bitr(diff_genes$Gene, fromType="SYMBOL", toType="ENTREZID", OrgDb="org.Hs.eg.db")
'select()' returned 1:1 mapping between keys and columns
eg_diff_genes <- diff_genes %>% left_join(., eg_diff_genes, by = c('Gene' = 'SYMBOL'))
eg_universe = bitr(top.table_OF_AD %>% as_tibble(rownames = 'Gene') %>% pull(Gene), fromType="SYMBOL", toType="ENTREZID", OrgDb="org.Hs.eg.db")
'select()' returned 1:many mapping between keys and columns
Warning in bitr(top.table_OF_AD %>% as_tibble(rownames = "Gene") %>% pull(Gene),  :
  0.01% of input gene IDs are fail to map...
eg_diff_gene_list <- eg_diff_genes$logFC
names(eg_diff_gene_list) <- eg_diff_genes$ENTREZID

egoOF <- enrichGO(gene          = eg_diff_genes$ENTREZID,
                     universe      = eg_universe$ENTREZID,
                     OrgDb         = org.Hs.eg.db,
                     ont           = "all",
                     readable      = TRUE)



p1 <- dotplot(egoOF, showCategory=20) + ggtitle("Dotplot for GO")
p1

NA
NA

Table

So you can see the genes in the ontology term.

egoOF@result %>% as_tibble() %>%  filter(p.adjust < 0.05) %>%  DT::datatable()

CNET Plot

Relationships between related GO terms with shared genes. Yellow means more expressed in the OF than the OC.

geneList <- eg_diff_genes$logFC
names(geneList) <- eg_diff_genes$Gene
cnet <- cnetplot(egoOF, foldChange = geneList, showCategory = 12) + scale_color_viridis_c(name = 'log2(FoldChange)')
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
cnet

Wikipathways

# system("wget https://wikipathways-data.wmcloud.org/current/gmt/wikipathways-20211110-gmt-Homo_sapiens.gmt")
wp2gene <- read.gmt('wikipathways-20211110-gmt-Homo_sapiens.gmt')
wp2gene <- wp2gene %>% tidyr::separate(term, c("name","version","wpid","org"), "%")
wpid2gene <- wp2gene %>% dplyr::select(wpid, gene) #TERM2GENE
wpid2name <- wp2gene %>% dplyr::select(wpid, name) #TERM2NAME

ewp <- enricher(eg_diff_genes$ENTREZID,
                TERM2GENE = wpid2gene,
                TERM2NAME = wpid2name,
                pvalueCutoff = 0.1)

ewp_plot <- dotplot(ewp, showCategory=10) + ggtitle("Dotplot for WikiPathways")
ewp_plot

Table

ewp <- setReadable(ewp, OrgDb =  org.Hs.eg.db, keyType = 'ENTREZID')
ewp@result %>% DT::datatable()

KEGG Pathway Enrichment

kk <- enrichKEGG(gene         = eg_diff_genes$ENTREZID, 
                 universe = eg_universe$ENTREZID,
                 organism     = 'hsa')
dotplot(kk) + ggtitle("KEGG Pathway Enrichment") 

Table

kk <- setReadable(kk, OrgDb =  org.Hs.eg.db, keyType = 'ENTREZID')
kk@result %>% DT::datatable()

My takeaway(s)

  1. Seeing a whole bunch of terms relating to cellular processes.
  2. A bit of visual function terms again - so as the fissure closes get retina dev continuing…but this is comparing against the OC. Is retinal specification driving from the fissure?
  3. DLX1/DLX2 interesting TF (retina cell specification as well as forebrain and drosophila head/limb stuffs)

Session Info

devtools::session_info()
─ Session info  πŸ™οΈ  πŸ™  πŸ‘¨β€πŸ‘§β€πŸ‘¦   ───────────────────────────────────────────────────────────────────────────────────────────
 hash: cityscape, slightly frowning face, family: man, girl, boy

 setting  value
 version  R version 4.1.2 (2021-11-01)
 os       macOS Catalina 10.15.7
 system   x86_64, darwin17.0
 ui       RStudio
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       America/New_York
 date     2021-12-14
 rstudio  2021.09.0+351 Ghost Orchid (desktop)
 pandoc   2.14.0.3 @ /Applications/RStudio.app/Contents/MacOS/pandoc/ (via rmarkdown)

─ Packages ────────────────────────────────────────────────────────────────────────────────────────────────────────────
 package              * version  date (UTC) lib source
 annotate               1.72.0   2021-10-26 [1] Bioconductor
 AnnotationDbi        * 1.56.1   2021-10-29 [1] Bioconductor
 ape                    5.5      2021-04-25 [1] CRAN (R 4.1.2)
 aplot                  0.1.1    2021-09-22 [1] CRAN (R 4.1.2)
 assertthat             0.2.1    2019-03-21 [1] CRAN (R 4.1.2)
 backports              1.3.0    2021-10-27 [1] CRAN (R 4.1.2)
 base64enc              0.1-3    2015-07-28 [1] CRAN (R 4.1.2)
 beeswarm               0.4.0    2021-06-01 [1] CRAN (R 4.1.0)
 Biobase              * 2.54.0   2021-10-26 [1] Bioconductor
 BiocFileCache          2.2.0    2021-10-26 [1] Bioconductor
 BiocGenerics         * 0.40.0   2021-10-26 [1] Bioconductor
 BiocManager            1.30.16  2021-06-15 [1] CRAN (R 4.1.0)
 BiocParallel         * 1.28.0   2021-10-26 [1] Bioconductor
 biomaRt              * 2.50.0   2021-10-26 [1] Bioconductor
 Biostrings             2.62.0   2021-10-26 [1] Bioconductor
 bit                    4.0.4    2020-08-04 [1] CRAN (R 4.1.2)
 bit64                  4.0.5    2020-08-30 [1] CRAN (R 4.1.2)
 bitops                 1.0-7    2021-04-24 [1] CRAN (R 4.1.2)
 blob                   1.2.2    2021-07-23 [1] CRAN (R 4.1.2)
 broom                  0.7.10   2021-10-31 [1] CRAN (R 4.1.2)
 bslib                  0.3.1    2021-10-06 [1] CRAN (R 4.1.0)
 cachem                 1.0.6    2021-08-19 [1] CRAN (R 4.1.0)
 callr                  3.7.0    2021-04-20 [1] CRAN (R 4.1.2)
 cellranger             1.1.0    2016-07-27 [1] CRAN (R 4.1.2)
 checkmate              2.0.0    2020-02-06 [1] CRAN (R 4.1.0)
 cli                    3.1.0    2021-10-27 [1] CRAN (R 4.1.2)
 cluster                2.1.2    2021-04-17 [1] CRAN (R 4.1.2)
 clusterProfiler      * 4.2.0    2021-10-26 [1] Bioconductor
 colorspace             2.0-2    2021-06-24 [1] CRAN (R 4.1.2)
 cowplot                1.1.1    2020-12-30 [1] CRAN (R 4.1.0)
 crayon                 1.4.2    2021-10-29 [1] CRAN (R 4.1.2)
 crosstalk              1.2.0    2021-11-04 [1] CRAN (R 4.1.0)
 curl                   4.3.2    2021-06-23 [1] CRAN (R 4.1.2)
 data.table             1.14.2   2021-09-27 [1] CRAN (R 4.1.2)
 DBI                    1.1.1    2021-01-15 [1] CRAN (R 4.1.2)
 dbplyr                 2.1.1    2021-04-06 [1] CRAN (R 4.1.2)
 DelayedArray           0.20.0   2021-10-26 [1] Bioconductor
 desc                   1.4.0    2021-09-28 [1] CRAN (R 4.1.2)
 devtools               2.4.2    2021-06-07 [1] CRAN (R 4.1.2)
 dichromat              2.0-0    2013-01-24 [1] CRAN (R 4.1.0)
 digest                 0.6.28   2021-09-23 [1] CRAN (R 4.1.2)
 DO.db                  2.9      2021-11-16 [1] Bioconductor
 DOSE                   3.20.0   2021-10-26 [1] Bioconductor
 downloader             0.4      2015-07-09 [1] CRAN (R 4.1.2)
 dplyr                * 1.0.7    2021-06-18 [1] CRAN (R 4.1.2)
 DT                     0.19     2021-09-02 [1] CRAN (R 4.1.0)
 edgeR                  3.36.0   2021-10-26 [1] Bioconductor
 ellipsis               0.3.2    2021-04-29 [1] CRAN (R 4.1.2)
 enrichplot           * 1.14.1   2021-10-31 [1] Bioconductor
 evaluate               0.14     2019-05-28 [1] CRAN (R 4.1.2)
 fansi                  0.5.0    2021-05-25 [1] CRAN (R 4.1.2)
 farver                 2.1.0    2021-02-28 [1] CRAN (R 4.1.2)
 fastmap                1.1.0    2021-01-25 [1] CRAN (R 4.1.2)
 fastmatch              1.1-3    2021-07-23 [1] CRAN (R 4.1.2)
 fgsea                  1.20.0   2021-10-26 [1] Bioconductor
 filelock               1.0.2    2018-10-05 [1] CRAN (R 4.1.2)
 forcats              * 0.5.1    2021-01-27 [1] CRAN (R 4.1.2)
 foreign                0.8-81   2020-12-22 [1] CRAN (R 4.1.2)
 Formula                1.2-4    2020-10-16 [1] CRAN (R 4.1.0)
 fs                     1.5.0    2020-07-31 [1] CRAN (R 4.1.2)
 genefilter             1.76.0   2021-10-26 [1] Bioconductor
 generics               0.1.1    2021-10-25 [1] CRAN (R 4.1.2)
 GenomeInfoDb           1.30.0   2021-10-26 [1] Bioconductor
 GenomeInfoDbData       1.2.7    2021-11-09 [1] Bioconductor
 GenomicRanges          1.46.0   2021-10-26 [1] Bioconductor
 ggbeeswarm             0.6.0    2017-08-07 [1] CRAN (R 4.1.0)
 ggforce                0.3.3    2021-03-05 [1] CRAN (R 4.1.2)
 ggfun                  0.0.4    2021-09-17 [1] CRAN (R 4.1.0)
 ggnewscale             0.4.5    2021-01-11 [1] CRAN (R 4.1.0)
 ggplot2              * 3.3.5    2021-06-25 [1] CRAN (R 4.1.2)
 ggplotify              0.1.0    2021-09-02 [1] CRAN (R 4.1.0)
 ggraph                 2.0.5    2021-02-23 [1] CRAN (R 4.1.2)
 ggrepel              * 0.9.1    2021-01-15 [1] CRAN (R 4.1.0)
 ggsci                  2.9      2018-05-14 [1] CRAN (R 4.1.0)
 ggtree                 3.2.0    2021-10-26 [1] Bioconductor
 glue                   1.5.0    2021-11-07 [1] CRAN (R 4.1.2)
 GO.db                  3.14.0   2021-11-16 [1] Bioconductor
 GOSemSim               2.20.0   2021-10-26 [1] Bioconductor
 graphlayouts           0.7.1    2020-10-26 [1] CRAN (R 4.1.2)
 gridExtra              2.3      2017-09-09 [1] CRAN (R 4.1.0)
 gridGraphics           0.5-1    2020-12-13 [1] CRAN (R 4.1.0)
 gtable                 0.3.0    2019-03-25 [1] CRAN (R 4.1.2)
 haven                  2.4.3    2021-08-04 [1] CRAN (R 4.1.2)
 Hmisc                  4.6-0    2021-10-07 [1] CRAN (R 4.1.0)
 hms                    1.1.1    2021-09-26 [1] CRAN (R 4.1.2)
 htmlTable              2.3.0    2021-10-12 [1] CRAN (R 4.1.0)
 htmltools              0.5.2    2021-08-25 [1] CRAN (R 4.1.2)
 htmlwidgets            1.5.4    2021-09-08 [1] CRAN (R 4.1.0)
 httr                   1.4.2    2020-07-20 [1] CRAN (R 4.1.2)
 igraph                 1.2.8    2021-11-07 [1] CRAN (R 4.1.2)
 IRanges              * 2.28.0   2021-10-26 [1] Bioconductor
 jpeg                   0.1-9    2021-07-24 [1] CRAN (R 4.1.0)
 jquerylib              0.1.4    2021-04-26 [1] CRAN (R 4.1.2)
 jsonlite               1.7.2    2020-12-09 [1] CRAN (R 4.1.2)
 KEGGREST               1.34.0   2021-10-26 [1] Bioconductor
 knitr                  1.36     2021-09-29 [1] CRAN (R 4.1.2)
 labeling               0.4.2    2020-10-20 [1] CRAN (R 4.1.2)
 lattice                0.20-45  2021-09-22 [1] CRAN (R 4.1.2)
 latticeExtra           0.6-29   2019-12-19 [1] CRAN (R 4.1.0)
 lazyeval               0.2.2    2019-03-15 [1] CRAN (R 4.1.0)
 lifecycle              1.0.1    2021-09-24 [1] CRAN (R 4.1.2)
 limma                  3.50.0   2021-10-26 [1] Bioconductor
 locfit                 1.5-9.4  2020-03-25 [1] CRAN (R 4.1.0)
 lubridate              1.8.0    2021-10-07 [1] CRAN (R 4.1.2)
 magrittr               2.0.1    2020-11-17 [1] CRAN (R 4.1.2)
 mapproj                1.2.7    2020-02-03 [1] CRAN (R 4.1.0)
 maps                   3.4.0    2021-09-25 [1] CRAN (R 4.1.0)
 MASS                   7.3-54   2021-05-03 [1] CRAN (R 4.1.2)
 Matrix                 1.3-4    2021-06-01 [1] CRAN (R 4.1.2)
 MatrixGenerics         1.6.0    2021-10-26 [1] Bioconductor
 matrixStats            0.61.0   2021-09-17 [1] CRAN (R 4.1.2)
 memoise                2.0.0    2021-01-26 [1] CRAN (R 4.1.0)
 mgcv                   1.8-38   2021-10-06 [1] CRAN (R 4.1.2)
 modelr                 0.1.8    2020-05-19 [1] CRAN (R 4.1.2)
 munsell                0.5.0    2018-06-12 [1] CRAN (R 4.1.2)
 nlme                   3.1-153  2021-09-07 [1] CRAN (R 4.1.2)
 nnet                   7.3-16   2021-05-03 [1] CRAN (R 4.1.2)
 org.Hs.eg.db         * 3.14.0   2021-11-16 [1] Bioconductor
 pals                   1.7      2021-04-17 [1] CRAN (R 4.1.0)
 patchwork              1.1.1    2020-12-17 [1] CRAN (R 4.1.0)
 pillar                 1.6.4    2021-10-18 [1] CRAN (R 4.1.2)
 pkgbuild               1.2.0    2020-12-15 [1] CRAN (R 4.1.2)
 pkgconfig              2.0.3    2019-09-22 [1] CRAN (R 4.1.2)
 pkgload                1.2.3    2021-10-13 [1] CRAN (R 4.1.2)
 plyr                   1.8.6    2020-03-03 [1] CRAN (R 4.1.2)
 png                    0.1-7    2013-12-03 [1] CRAN (R 4.1.2)
 polyclip               1.10-0   2019-03-14 [1] CRAN (R 4.1.2)
 prettyunits            1.1.1    2020-01-24 [1] CRAN (R 4.1.2)
 processx               3.5.2    2021-04-30 [1] CRAN (R 4.1.2)
 progress               1.2.2    2019-05-16 [1] CRAN (R 4.1.2)
 ps                     1.6.0    2021-02-28 [1] CRAN (R 4.1.2)
 purrr                * 0.3.4    2020-04-17 [1] CRAN (R 4.1.2)
 qsmooth              * 1.10.0   2021-10-26 [1] Bioconductor
 qvalue                 2.26.0   2021-10-26 [1] Bioconductor
 R6                     2.5.1    2021-08-19 [1] CRAN (R 4.1.2)
 rappdirs               0.3.3    2021-01-31 [1] CRAN (R 4.1.2)
 RColorBrewer           1.1-2    2014-12-07 [1] CRAN (R 4.1.2)
 Rcpp                   1.0.7    2021-07-07 [1] CRAN (R 4.1.2)
 RCurl                  1.98-1.5 2021-09-17 [1] CRAN (R 4.1.2)
 readr                * 2.0.2    2021-09-27 [1] CRAN (R 4.1.2)
 readxl                 1.3.1    2019-03-13 [1] CRAN (R 4.1.0)
 remotes                2.4.1    2021-09-29 [1] CRAN (R 4.1.2)
 reprex                 2.0.1    2021-08-05 [1] CRAN (R 4.1.2)
 reshape2               1.4.4    2020-04-09 [1] CRAN (R 4.1.2)
 rlang                  0.4.12   2021-10-18 [1] CRAN (R 4.1.2)
 rmarkdown              2.11     2021-09-14 [1] CRAN (R 4.1.2)
 rpart                  4.1-15   2019-04-12 [1] CRAN (R 4.1.2)
 rprojroot              2.0.2    2020-11-15 [1] CRAN (R 4.1.2)
 RSQLite                2.2.8    2021-08-21 [1] CRAN (R 4.1.0)
 rstudioapi             0.13     2020-11-12 [1] CRAN (R 4.1.2)
 rvest                  1.0.2    2021-10-16 [1] CRAN (R 4.1.2)
 S4Vectors            * 0.32.2   2021-11-07 [1] Bioconductor
 sass                   0.4.0    2021-05-12 [1] CRAN (R 4.1.0)
 scales                 1.1.1    2020-05-11 [1] CRAN (R 4.1.2)
 scatterpie             0.1.7    2021-08-20 [1] CRAN (R 4.1.2)
 sessioninfo            1.2.1    2021-11-02 [1] CRAN (R 4.1.2)
 shadowtext             0.0.9    2021-09-19 [1] CRAN (R 4.1.2)
 stringi                1.7.5    2021-10-04 [1] CRAN (R 4.1.2)
 stringr              * 1.4.0    2019-02-10 [1] CRAN (R 4.1.2)
 SummarizedExperiment   1.24.0   2021-10-26 [1] Bioconductor
 survival               3.2-13   2021-08-24 [1] CRAN (R 4.1.2)
 sva                    3.42.0   2021-10-26 [1] Bioconductor
 testthat               3.1.0    2021-10-04 [1] CRAN (R 4.1.2)
 tibble               * 3.1.6    2021-11-07 [1] CRAN (R 4.1.2)
 tidygraph              1.2.0    2020-05-12 [1] CRAN (R 4.1.2)
 tidyr                * 1.1.4    2021-09-27 [1] CRAN (R 4.1.2)
 tidyselect             1.1.1    2021-04-30 [1] CRAN (R 4.1.2)
 tidytree               0.3.6    2021-11-12 [1] CRAN (R 4.1.2)
 tidyverse            * 1.3.1    2021-04-15 [1] CRAN (R 4.1.2)
 treeio                 1.18.1   2021-11-14 [1] Bioconductor
 tweenr                 1.0.2    2021-03-23 [1] CRAN (R 4.1.2)
 tzdb                   0.2.0    2021-10-27 [1] CRAN (R 4.1.2)
 usethis                2.1.3    2021-10-27 [1] CRAN (R 4.1.2)
 utf8                   1.2.2    2021-07-24 [1] CRAN (R 4.1.2)
 vctrs                  0.3.8    2021-04-29 [1] CRAN (R 4.1.2)
 vipor                  0.4.5    2017-03-22 [1] CRAN (R 4.1.0)
 viridis                0.6.2    2021-10-13 [1] CRAN (R 4.1.0)
 viridisLite            0.4.0    2021-04-13 [1] CRAN (R 4.1.2)
 vroom                  1.5.5    2021-09-14 [1] CRAN (R 4.1.2)
 withr                  2.4.2    2021-04-18 [1] CRAN (R 4.1.2)
 xfun                   0.28     2021-11-04 [1] CRAN (R 4.1.2)
 XML                    3.99-0.8 2021-09-17 [1] CRAN (R 4.1.2)
 xml2                   1.3.2    2020-04-23 [1] CRAN (R 4.1.0)
 xtable                 1.8-4    2019-04-21 [1] CRAN (R 4.1.2)
 XVector                0.34.0   2021-10-26 [1] Bioconductor
 yaml                   2.2.1    2020-02-01 [1] CRAN (R 4.1.2)
 yulab.utils            0.0.4    2021-10-09 [1] CRAN (R 4.1.0)
 zlibbioc               1.40.0   2021-10-26 [1] Bioconductor

 [1] /Library/Frameworks/R.framework/Versions/4.1/Resources/library

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
LS0tCnRpdGxlOiAiT0Y6IER1cmluZyB2cyBBZnRlciIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdGhlbWU6IGZsYXRseQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogaGlkZQotLS0KCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShiaW9tYVJ0KQpsaWJyYXJ5KGdncmVwZWwpCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQpsaWJyYXJ5KGVucmljaHBsb3QpCiMgUGFyYWxsZWwKbGlicmFyeShCaW9jUGFyYWxsZWwpCnJlZ2lzdGVyKE11bHRpY29yZVBhcmFtKDYpKQoKbG9hZCgnLi4vZGF0YS9taWNyb2FycmF5X05HU19vYmplY3RzLlJkYXRhJykKbG9hZCgnLi4vZGF0YS90b3BfdGFibGVzLlJkYXRhJykKc3ZhX2NvdW50cyA8LSByZWFkX3RzdignLi4vZGF0YS9zdmFfY291bnRzLnRzdi5neicpCgpzYW1wbGVfbWV0YV9EIDwtIHNhbXBsZV9tZXRhICU+JSBmaWx0ZXIoU2FtcGxlICVpbiUgY29sbmFtZXMoc3ZhX2NvdW50cykpICU+JQogIGRwbHlyOjpzZWxlY3QoU2FtcGxlOlNlY3Rpb24sIExheW91dDpGdXNpb24pICU+JQogIG11dGF0ZShTMiA9IGNhc2Vfd2hlbihTZWN0aW9uID09ICdPRicgfiAnT0YnLCBUUlVFIH4gJ09DJykpICU+JQogIHVuaXF1ZSgpCgpib3hfbWFrZXIgPC0gZnVuY3Rpb24odGFibGUsIGdlbmVzLCBzZWN0aW9uID0gYygnT0YnLCdPQycpLCB0eXBlID0gJ3RlbXBvcmFsJyl7CiAgaWYgKCdtYXRyaXgnICVpbiUgY2xhc3ModGFibGUpKXsKICAgIHRhYmxlIDwtIHRhYmxlICU+JQogICAgICBhc190aWJibGUocm93bmFtZXMgPSAnR2VuZScpCiAgfQogIGlmICh0eXBlID09ICd0ZW1wb3JhbCcpewogICAgcGxvdCA8LSB0YWJsZSAlPiUgCiAgICAgIHBpdm90X2xvbmdlcigtR2VuZSwgbmFtZXNfdG8gPSAnU2FtcGxlJywgdmFsdWVzX3RvID0gJ0V4cHJlc3Npb24nKSAlPiUKICAgICAgbXV0YXRlKFNhbXBsZSA9IGdzdWIoJ18uKnwuQ0VMLionLCcnLFNhbXBsZSkpICU+JQogICAgICBsZWZ0X2pvaW4oc2FtcGxlX21ldGFfRCkgJT4lCiAgICAgIG11dGF0ZShTMiA9IGNhc2Vfd2hlbihTZWN0aW9uID09ICdPRicgfiAnT0YnLFRSVUUgfiAnT0MnKSkgJT4lCiAgICAgIGZpbHRlcihHZW5lICVpbiUgZ2VuZXMsIFMyICVpbiUgc2VjdGlvbikgJT4lCiAgICAgICNmaWx0ZXIoR2VuZSAlaW4lIHJvdy5uYW1lcyh0b3AudGFibGVfT0ZfQUQgJT4lIGhlYWQoMTApKSkgJT4lCiAgICAgIG11dGF0ZShGdXNpb24gPSBmYWN0b3IoRnVzaW9uLCBsZXZlbHMgPSBjKCdCZWZvcmUnLCdEdXJpbmcnLCdBZnRlcicpKSkgJT4lCiAgICAgIG11dGF0ZShPcmdUZWNoID0gcGFzdGUoT3JnYW5pc20sIFRlY2hub2xvZ3ksIHNlcCA9ICdfJykpICU+JSAKICAgICAgZ2dwbG90KGFlcyh4PUZ1c2lvbiwgeT1FeHByZXNzaW9uLCBjb2xvciA9IE9yZ2FuaXNtLCBzaGFwZSA9IFRlY2hub2xvZ3kpKSArCiAgICAgICMgZ2VvbV9ib3hwbG90KGFlcyhncm91cCA9IEZ1c2lvbiksIGNvbG9yID0gJ0JsYWNrJywgb3V0bGllci5jb2xvdXIgPSBOQSkgKwogICAgICAjIGdlb21fYm94cGxvdChhZXMoZ3JvdXAgPSBpbnRlcmFjdGlvbihPcmdhbmlzbSxGdXNpb24pKSwgb3V0bGllci5jb2xvdXIgPSBOQSkgKwogICAgICBnZ2JlZXN3YXJtOjpnZW9tX3F1YXNpcmFuZG9tKHNpemUgPSAzLCBhbHBoYSA9IDAuNykgKwogICAgICBjb3dwbG90Ojp0aGVtZV9jb3dwbG90KCkgKwogICAgICBmYWNldF9ncmlkKH5HZW5lICsgUzIsIHNjYWxlcyA9ICdmcmVlX3knKSArCiAgICAgIGdnc2NpOjpzY2FsZV9jb2xvcl9hYWFzKCkgKwogICAgICB5bGFiKCdsb2cyIChjb3JyZWN0ZWQgY291bnRzKScpICsKICAgICAgc3RhdF9zdW1tYXJ5KGZ1bj1tZWFuLCBnZW9tID0gJ2xpbmUnLCBhZXMoZ3JvdXAgPSBPcmdUZWNoLCBjb2xvciA9IE9yZ2FuaXNtKSkgfQogIGVsc2UgewogICAgcGxvdCA8LSB0YWJsZSAlPiUgCiAgICAgIHBpdm90X2xvbmdlcigtR2VuZSwgbmFtZXNfdG8gPSAnU2FtcGxlJywgdmFsdWVzX3RvID0gJ0V4cHJlc3Npb24nKSAlPiUKICAgICAgbXV0YXRlKFNhbXBsZSA9IGdzdWIoJ18uKnwuQ0VMLionLCcnLFNhbXBsZSkpICU+JQogICAgICBsZWZ0X2pvaW4oc2FtcGxlX21ldGFfRCkgJT4lCiAgICAgIG11dGF0ZShTMiA9IGNhc2Vfd2hlbihTZWN0aW9uID09ICdPRicgfiAnT0YnLFRSVUUgfiAnT0MnKSkgJT4lCiAgICAgIGZpbHRlcihHZW5lICVpbiUgZ2VuZXMsIFMyICVpbiUgc2VjdGlvbikgJT4lCiAgICAgIG11dGF0ZShGdXNpb24gPSBmYWN0b3IoRnVzaW9uLCBsZXZlbHMgPSBjKCdCZWZvcmUnLCdEdXJpbmcnLCdBZnRlcicpKSkgJT4lCiAgICAgIGZpbHRlcihGdXNpb24gPT0gJ0R1cmluZycpICU+JSAKICAgICAgbXV0YXRlKE9yZ1RlY2ggPSBwYXN0ZShPcmdhbmlzbSwgVGVjaG5vbG9neSwgc2VwID0gJ18nKSkgJT4lIAogICAgICBnZ3Bsb3QoYWVzKHg9UzIsIHk9RXhwcmVzc2lvbiwgY29sb3IgPSBPcmdhbmlzbSwgc2hhcGUgPSBUZWNobm9sb2d5KSkgKwogICAgICAjIGdlb21fYm94cGxvdChhZXMoZ3JvdXAgPSBGdXNpb24pLCBjb2xvciA9ICdCbGFjaycsIG91dGxpZXIuY29sb3VyID0gTkEpICsKICAgICAgIyBnZW9tX2JveHBsb3QoYWVzKGdyb3VwID0gaW50ZXJhY3Rpb24oT3JnYW5pc20sRnVzaW9uKSksIG91dGxpZXIuY29sb3VyID0gTkEpICsKICAgICAgZ2diZWVzd2FybTo6Z2VvbV9xdWFzaXJhbmRvbShzaXplID0gMywgYWxwaGEgPSAwLjcpICsKICAgICAgY293cGxvdDo6dGhlbWVfY293cGxvdCgpICsKICAgICAgZ2dzY2k6OnNjYWxlX2NvbG9yX2FhYXMoKSArCiAgICAgIHlsYWIoJ2xvZzIgKGNvcnJlY3RlZCBjb3VudHMpJykgKwogICAgICB4bGFiKCdTZWN0aW9uJykgKwogICAgICBzdGF0X3N1bW1hcnkoZnVuPW1lYW4sIGdlb20gPSAnbGluZScsIGFlcyhncm91cCA9IE9yZ1RlY2gsIGNvbG9yID0gT3JnYW5pc20pKSArIGZhY2V0X3dyYXAofkdlbmUpCiAgfQogIHBsb3QKfQoKdm9sY2Fub19tYWtlciA8LSBmdW5jdGlvbihkZiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9IlZvbGNhbm8gUGxvdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHB2YWx1ZT0nUC5WYWx1ZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHBhZGo9J2Fkai5QLlZhbCcsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ0ZDPSdsb2dGQycsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVfbGlzdCA9ICcnKXsKICBkZiRwdmFsdWUgPC0gZGZbLHB2YWx1ZV0KICBkZiRsb2cyRm9sZENoYW5nZSA8LSBkZlssbG9nRkNdCiAgZGYkcGFkaiA8LSBkZlsscGFkal0KICBkZiRHZW5lIDwtIHJvdy5uYW1lcyhkZikKICBkZiA8LSBkZlshaXMubmEoZGYkcHZhbHVlKSxdCiAgcHJpbnQoZGltKGRmKSkKICAKICBkZiA8LSBkZiAlPiUgbXV0YXRlKENsYXNzID0gY2FzZV93aGVuKHBhZGogPCAwLjA1ICYgYWJzKGxvZ0ZDKSA+IDF+ICJGRFIgPCAwLjA1ICYgbG9nRkMgPiAxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZGogPCAwLjEgJiBhYnMobG9nRkMpID4gMSB+ICdGRFIgPCAwLjEgJiBsb2dGQyA+IDEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICdOb3Qgc2lnbmlmaWNhbnQnKSkKICBkZiRHZW5lVCA8LSBkZiRHZW5lCiAgaWYgKGdlbmVfbGlzdCA9PSAnJyl7CiAgICBnZW5lX2xpc3QgPC0gZGYgJT4lIGZpbHRlcihwYWRqIDwgMC4wNSkgJT4lIHB1bGwoR2VuZSkgJT4lIGhlYWQoMTApCiAgfQogIGRmJEdlbmVbIWRmJEdlbmUgJWluJSBnZW5lX2xpc3RdIDwtICcnCiAgCiAgcGxvdCA8LSBnZ3Bsb3QoZGF0YT1kZixhZXMobGFiZWw9R2VuZSwgeCA9IGxvZzJGb2xkQ2hhbmdlLCB5ID0gLWxvZzEwKHB2YWx1ZSkpKSArCiAgICBnZW9tX3BvaW50KGFlcyhjb2xvdXI9Q2xhc3MpKSArCiAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1jKCJkYXJrcmVkIiwgInJlZCIsICJncmV5IikpICsKICAgIGNvd3Bsb3Q6OnRoZW1lX2Nvd3Bsb3QoKSArCiAgICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0PS0xKSxsaW5ldHlwZT0iZG90dGVkIikgKwogICAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD0xKSxsaW5ldHlwZT0iZG90dGVkIikgKwogICAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD0tMiksbGluZXR5cGU9ImRvdHRlZCIpICsKICAgIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9MiksbGluZXR5cGU9ImRvdHRlZCIpICsKICAgIGdlb21fbGFiZWxfcmVwZWwobWF4Lm92ZXJsYXBzID0gMTAwKSArCiAgICB4bGFiKCdsb2dGQycpICsgeWxhYignLWxvZzEwKHAgdmFsdWUpJykgKwogICAgZ2d0aXRsZSh0aXRsZSkgKyBjb3dwbG90Ojp0aGVtZV9jb3dwbG90KCkKICAKICBwbG90Cn0KYGBgCgojIER1cmluZyB2cyBBZnRlciAoT0YpCgoyMDIxLTEyLTEzCgoqKlBvc2l0aXZlIG1lYW5zIGhpZ2hlciBleHByZXNzaW9uIGluIHRoZSBBZnRlciByZWxhdGl2ZSB0byB0aGUgRHVyaW5nIHRpbWUgcG9pbnQgKGFtb25nIE9GIHNhbXBsZXMgb25seSkqKiAKCiMjIFZvbGNhbm8KCmBgYHtyLCBmaWcud2lkdGg9NSwgZmlnLmhlaWdodD0yfQp2b2xjYW5vX21ha2VyKHRvcC50YWJsZV9PRl9BRCwgdGl0bGUgPSAnT0Y6IER1cmluZyB2cyBBZnRlcicsCiAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgZ2VuZV9saXN0ID0gYyh0b3AudGFibGVfT0ZfQUQgJT4lIGZpbHRlcihsb2dGQyA+IDApICU+JSBoZWFkKDEyKSAlPiUgcm93Lm5hbWVzKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3AudGFibGVfT0ZfQUQgJT4lIGZpbHRlcihsb2dGQyA8IDApICU+JSBoZWFkKDEyKSAlPiUgcm93Lm5hbWVzKCkpKQpgYGAKCiMjIERpZmYgVGFibGUKCkdlbmVzIHdpdGggYW4gRkRSIDwgMC4xIGluIHRoaXMgdGVzdC4gCgpgYGB7cn0KdG9wLnRhYmxlX09GX0FEICU+JSBhc190aWJibGUocm93bmFtZXMgPSAnR2VuZScpICU+JSBmaWx0ZXIoYWRqLlAuVmFsIDwgMC4xKSAlPiUgIERUOjpkYXRhdGFibGUoKQpgYGAKCiMjIEV4cHJlc3Npb24gb2YgdG9wIDYgZ2VuZXMgKGJ5IEZEUikgYWNyb3NzIHNlY3Rpb24gYW5kIHN0YWdlCgpDb2xvcmVkIGJ5IG9yZ2FuaXNtLiBFYWNoIGxpbmUgaXMgZHJhd24gZm9yIG9yZ2FuaXNtIC8gdGVjaG5vbG9neSAocmVtZW1iZXIsIG1vdXNlIGhhcyBib3RoIG1pY3JvYXJyYXkgYW5kIFJOQS1zZXEpLgoKIyMjIFVwIChnZW5lcyB0aGF0IGdvIHVwIGluIGV4cHJlc3Npb24gRHVyaW5nIC0+IEFmdGVyKQpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTN9CmJveF9tYWtlcihzdmFfY291bnRzLCAKICAgICAgICAgIGdlbmVzID0gdG9wLnRhYmxlX09GX0FEICU+JSAKICAgICAgICAgICAgYXNfdGliYmxlKHJvd25hbWVzID0gJ0dlbmUnKSAlPiUgCiAgICAgICAgICAgIGZpbHRlcihhZGouUC5WYWwgPCAwLjA1LCBsb2dGQyA+IDApICU+JSBoZWFkKDEwKSAlPiUgcHVsbChHZW5lKSwKICAgICAgICAgIHNlY3Rpb24gPSBjKCdPRicpLCB0eXBlID0gJ3RlbXBvcmFsJykKYGBgCgojIyMgRG93bgpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTN9CmJveF9tYWtlcihzdmFfY291bnRzLCAKICAgICAgICAgIGdlbmVzID0gdG9wLnRhYmxlX09GX0FEICU+JSAKICAgICAgICAgICAgYXNfdGliYmxlKHJvd25hbWVzID0gJ0dlbmUnKSAlPiUgCiAgICAgICAgICAgIGZpbHRlcihhZGouUC5WYWwgPCAwLjA1LCBsb2dGQyA8IDApICU+JSBoZWFkKDEwKSAlPiUgcHVsbChHZW5lKSwKICAgICAgICAgIHNlY3Rpb24gPSBjKCdPRicpLCB0eXBlID0gJ3RlbXBvcmFsJykKCgpgYGAKCiMgRW5yaWNobWVudCBBbmFseXNpcyAoR08sIEdTRUEpIAoKIyMgIEdTRUEKCkdTRUEgdXNlcyBhICpyYW5rZWQgbGlzdCogb2YgZ2VuZXMgYnkgbG9nRkMuIFNvIHRoZSBwIHZhbHVlcyBhcmUgbm90IHVzZWQgaW4gdGhpcyBzaXR1YXRpb24uIFRoZSAqb3JkZXIqIGlzLiBTbyB0aGUgR1NFQSBpcyB1c2VmdWwgaW4gc2l0dWF0aW9ucyB3aGVyZSB0aGVyZSBhcmUgdmVyeSBmZXcgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzLiAKCkFjdGl2YXRlZCB0ZXJtcyAoaGlnaGVyIGluIHRoZSAiQWZ0ZXIiKSByZWxhdGUgdG8gaW9uIGNoYW5uZWxzIGFuZCBjZWxsIGFkaGVzaW9uLiBTdXBwcmVzc2VkIHRlcm1zIChnZW5lcyBoaWdoZXIgZXhwcmVzc2VkIGluIHRoZSBEdXJpbmcpIHJlbGF0ZSB0byBjZWxsIGN5Y2xlIGFuZCBtZXRhYm9saXNtLiAKCiMjIyBEb3RwbG90CgpgYGB7ciwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9Nn0KYWxsX2dlbmVzIDwtIGJpdHIodG9wLnRhYmxlX09GX0FEICU+JSBhc190aWJibGUocm93bmFtZXMgPSAnR2VuZScpICU+JSBmaWx0ZXIoIWdyZXBsKCdSUFN8UlBMJywgR2VuZSkpICU+JSBwdWxsKEdlbmUpLCBmcm9tVHlwZT0iU1lNQk9MIiwgdG9UeXBlPSJFTlRSRVpJRCIsIE9yZ0RiPSJvcmcuSHMuZWcuZGIiKQphbGxfZ2VuZXMgPC0gYWxsX2dlbmVzICU+JSBsZWZ0X2pvaW4odG9wLnRhYmxlX09GX0FEICU+JSBhc190aWJibGUocm93bmFtZXMgPSAnU1lNQk9MJyksIGJ5ID0gYygnU1lNQk9MJykpCgpsb2dGQyA8LSBhbGxfZ2VuZXMkbG9nRkMKbmFtZXMobG9nRkMpIDwtIGFsbF9nZW5lcyRFTlRSRVpJRApsb2dGQyA8LSBuYS5vbWl0KGxvZ0ZDKQoKbG9nRkMgPSBzb3J0KGxvZ0ZDLCBkZWNyZWFzaW5nID0gVFJVRSkKCmdzZSA8LSBnc2VHTyhnZW5lTGlzdD1sb2dGQywKICAgICAgICAgICAgIG9udCA9IkFMTCIsCiAgICAgICAgICAgICBrZXlUeXBlID0gIkVOVFJFWklEIiwKICAgICAgICAgICAgIHB2YWx1ZUN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICBPcmdEYiA9IG9yZy5Icy5lZy5kYiwKICAgICAgICAgICAgIHBBZGp1c3RNZXRob2QgPSAiQkgiLAogICAgICAgICAgICAgZXBzID0gMCkKZ3NlIDwtIHNldFJlYWRhYmxlKGdzZSwgT3JnRGIgPSBvcmcuSHMuZWcuZGIpCiMgY2hhbmdlIHNvcnQgbG9naWMKZ3NlRiA8LSBnc2UKZ3NlRkByZXN1bHQgPC0gcmJpbmQoZ3NlRkByZXN1bHQgJT4lIGFycmFuZ2UoTkVTKSAlPiUgaGVhZCgyMCksCiAgICAgICAgICAgICAgICAgICAgIGdzZUZAcmVzdWx0ICU+JSBhcnJhbmdlKE5FUykgJT4lIHRhaWwoMjApICU+JSBhcnJhbmdlKC1ORVMpCikKZG90cGxvdChnc2UsIHNob3dDYXRlZ29yeT0xNSwgc3BsaXQ9Ii5zaWduIikgKyBmYWNldF9ncmlkKC5+LnNpZ24pICsgY293cGxvdDo6dGhlbWVfY293cGxvdCgpCmBgYAoKIyMjIFJlbGF0ZWQgdGVybXMKClNvIHdlIGNhbiBzZWUgImNodW5rcyIgb2YgdGVybXMgdGhhdCBnbyB0b2dldGhlci4gV2Ugc2VlIHNldmVyYWwgdGVybXMgcmVsYXRpbmcgdG8gaW9uIGNoYW5uZWxzIGFuZCBzeW5hcHRpYyBzaWduYWxsaW5nLgpgYGB7ciwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NH0KZ3NlUFQgPC0gcGFpcndpc2VfdGVybXNpbShnc2UpCmVtYXBwbG90KGdzZVBUKQpgYGAKCiMjIyBUYWJsZQoKU28geW91IGNhbiBzZWUgdGhlIGdlbmVzIGluIHRoZSBvbnRvbG9neSB0ZXJtLiBUaGUgZ2VuZXMgZ2V0ICJpbmNsdWRlZCIgYXMgZW5yaWNoZWQgaWYgR1NFQSBkZWVtcyB0aGVtIHRvIGJlIHJhbmtlZCB1bnVzdWFsbHkgaGlnaC4KCmBgYHtyfQpnc2VAcmVzdWx0ICU+JSBhc190aWJibGUoKSAlPiUgYXJyYW5nZSgtYWJzKE5FUykpICU+JSBmaWx0ZXIocC5hZGp1c3QgPCAwLjA1KSAlPiUgIERUOjpkYXRhdGFibGUoKQpgYGAKCiMjIEdPIEVucmljaG1lbnQgCgpHTyBlbnJpY2htZW50IHVzZXMgYSAqY3V0b2ZmKiBiZXR3ZWVuIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcyAoRkRSIDwgMC4xIGluIHRoaXMgY2FzZSkgYW5kIGV2ZXJ5dGhpbmcgZWxzZS4gCgpMb2FkcyBvZiBzdHVmZiByZWxhdGluZyB0byB2aXN1YWwgZnVuY3Rpb24gYW5kIGRldmVsb3BtZW50LiAKYGBge3IsIGZpZy53aWR0aD03fQoKZGlmZl9nZW5lcyA8LSB0b3AudGFibGVfT0ZfQUQgJT4lIGFzX3RpYmJsZShyb3duYW1lcyA9ICdHZW5lJykgJT4lIGZpbHRlcihhZGouUC5WYWwgPCAwLjEsICFncmVwbCgnUlBMfFJQUycsIEdlbmUpKSAKZWdfZGlmZl9nZW5lcyA8LSBiaXRyKGRpZmZfZ2VuZXMkR2VuZSwgZnJvbVR5cGU9IlNZTUJPTCIsIHRvVHlwZT0iRU5UUkVaSUQiLCBPcmdEYj0ib3JnLkhzLmVnLmRiIikKZWdfZGlmZl9nZW5lcyA8LSBkaWZmX2dlbmVzICU+JSBsZWZ0X2pvaW4oLiwgZWdfZGlmZl9nZW5lcywgYnkgPSBjKCdHZW5lJyA9ICdTWU1CT0wnKSkKZWdfdW5pdmVyc2UgPSBiaXRyKHRvcC50YWJsZV9PRl9BRCAlPiUgYXNfdGliYmxlKHJvd25hbWVzID0gJ0dlbmUnKSAlPiUgcHVsbChHZW5lKSwgZnJvbVR5cGU9IlNZTUJPTCIsIHRvVHlwZT0iRU5UUkVaSUQiLCBPcmdEYj0ib3JnLkhzLmVnLmRiIikKCmVnX2RpZmZfZ2VuZV9saXN0IDwtIGVnX2RpZmZfZ2VuZXMkbG9nRkMKbmFtZXMoZWdfZGlmZl9nZW5lX2xpc3QpIDwtIGVnX2RpZmZfZ2VuZXMkRU5UUkVaSUQKCmVnb09GIDwtIGVucmljaEdPKGdlbmUgICAgICAgICAgPSBlZ19kaWZmX2dlbmVzJEVOVFJFWklELAogICAgICAgICAgICAgICAgICAgICB1bml2ZXJzZSAgICAgID0gZWdfdW5pdmVyc2UkRU5UUkVaSUQsCiAgICAgICAgICAgICAgICAgICAgIE9yZ0RiICAgICAgICAgPSBvcmcuSHMuZWcuZGIsCiAgICAgICAgICAgICAgICAgICAgIG9udCAgICAgICAgICAgPSAiYWxsIiwKICAgICAgICAgICAgICAgICAgICAgcmVhZGFibGUgICAgICA9IFRSVUUpCgoKCnAxIDwtIGRvdHBsb3QoZWdvT0YsIHNob3dDYXRlZ29yeT0yMCkgKyBnZ3RpdGxlKCJEb3RwbG90IGZvciBHTyIpCnAxCgoKYGBgCiMjIyBUYWJsZQoKU28geW91IGNhbiBzZWUgdGhlIGdlbmVzIGluIHRoZSBvbnRvbG9neSB0ZXJtLgpgYGB7cn0KZWdvT0ZAcmVzdWx0ICU+JSBhc190aWJibGUoKSAlPiUgIGZpbHRlcihwLmFkanVzdCA8IDAuMDUpICU+JSAgRFQ6OmRhdGF0YWJsZSgpCmBgYAoKIyMjIENORVQgUGxvdAoKUmVsYXRpb25zaGlwcyBiZXR3ZWVuIHJlbGF0ZWQgR08gdGVybXMgd2l0aCBzaGFyZWQgZ2VuZXMuIFllbGxvdyBtZWFucyBtb3JlIGV4cHJlc3NlZCBpbiB0aGUgT0YgdGhhbiB0aGUgT0MuCmBgYHtyLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQpnZW5lTGlzdCA8LSBlZ19kaWZmX2dlbmVzJGxvZ0ZDCm5hbWVzKGdlbmVMaXN0KSA8LSBlZ19kaWZmX2dlbmVzJEdlbmUKY25ldCA8LSBjbmV0cGxvdChlZ29PRiwgZm9sZENoYW5nZSA9IGdlbmVMaXN0LCBzaG93Q2F0ZWdvcnkgPSAxMikgKyBzY2FsZV9jb2xvcl92aXJpZGlzX2MobmFtZSA9ICdsb2cyKEZvbGRDaGFuZ2UpJykKY25ldApgYGAKCiMgV2lraXBhdGh3YXlzCgpgYGB7cn0KIyBzeXN0ZW0oIndnZXQgaHR0cHM6Ly93aWtpcGF0aHdheXMtZGF0YS53bWNsb3VkLm9yZy9jdXJyZW50L2dtdC93aWtpcGF0aHdheXMtMjAyMTExMTAtZ210LUhvbW9fc2FwaWVucy5nbXQiKQp3cDJnZW5lIDwtIHJlYWQuZ210KCd3aWtpcGF0aHdheXMtMjAyMTExMTAtZ210LUhvbW9fc2FwaWVucy5nbXQnKQp3cDJnZW5lIDwtIHdwMmdlbmUgJT4lIHRpZHlyOjpzZXBhcmF0ZSh0ZXJtLCBjKCJuYW1lIiwidmVyc2lvbiIsIndwaWQiLCJvcmciKSwgIiUiKQp3cGlkMmdlbmUgPC0gd3AyZ2VuZSAlPiUgZHBseXI6OnNlbGVjdCh3cGlkLCBnZW5lKSAjVEVSTTJHRU5FCndwaWQybmFtZSA8LSB3cDJnZW5lICU+JSBkcGx5cjo6c2VsZWN0KHdwaWQsIG5hbWUpICNURVJNMk5BTUUKCmV3cCA8LSBlbnJpY2hlcihlZ19kaWZmX2dlbmVzJEVOVFJFWklELAogICAgICAgICAgICAgICAgVEVSTTJHRU5FID0gd3BpZDJnZW5lLAogICAgICAgICAgICAgICAgVEVSTTJOQU1FID0gd3BpZDJuYW1lLAogICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4xKQoKZXdwX3Bsb3QgPC0gZG90cGxvdChld3AsIHNob3dDYXRlZ29yeT0xMCkgKyBnZ3RpdGxlKCJEb3RwbG90IGZvciBXaWtpUGF0aHdheXMiKQpld3BfcGxvdApgYGAKIyMgVGFibGUKYGBge3J9CmV3cCA8LSBzZXRSZWFkYWJsZShld3AsIE9yZ0RiID0gIG9yZy5Icy5lZy5kYiwga2V5VHlwZSA9ICdFTlRSRVpJRCcpCmV3cEByZXN1bHQgJT4lIERUOjpkYXRhdGFibGUoKQpgYGAKCiMgS0VHRyBQYXRod2F5IEVucmljaG1lbnQKCmBgYHtyfQprayA8LSBlbnJpY2hLRUdHKGdlbmUgICAgICAgICA9IGVnX2RpZmZfZ2VuZXMkRU5UUkVaSUQsIAogICAgICAgICAgICAgICAgIHVuaXZlcnNlID0gZWdfdW5pdmVyc2UkRU5UUkVaSUQsCiAgICAgICAgICAgICAgICAgb3JnYW5pc20gICAgID0gJ2hzYScpCmRvdHBsb3Qoa2spICsgZ2d0aXRsZSgiS0VHRyBQYXRod2F5IEVucmljaG1lbnQiKSAKYGBgCgojIyBUYWJsZQpgYGB7cn0Ka2sgPC0gc2V0UmVhZGFibGUoa2ssIE9yZ0RiID0gIG9yZy5Icy5lZy5kYiwga2V5VHlwZSA9ICdFTlRSRVpJRCcpCmtrQHJlc3VsdCAlPiUgRFQ6OmRhdGF0YWJsZSgpCmBgYAoKCiMgTXkgdGFrZWF3YXkocykKCjEuIFNlZWluZyBhIHdob2xlIGJ1bmNoIG9mIHRlcm1zIHJlbGF0aW5nIHRvIGNlbGx1bGFyIHByb2Nlc3Nlcy4gCjIuIEEgYml0IG9mIHZpc3VhbCBmdW5jdGlvbiB0ZXJtcyBhZ2FpbiAtIHNvIGFzIHRoZSBmaXNzdXJlIGNsb3NlcyBnZXQgcmV0aW5hIGRldiBjb250aW51aW5nLi4uYnV0IHRoaXMgaXMgY29tcGFyaW5nIGFnYWluc3QgdGhlIE9DLiBJcyByZXRpbmFsIHNwZWNpZmljYXRpb24gZHJpdmluZyAqZnJvbSogdGhlIGZpc3N1cmU/CjMuIERMWDEvRExYMiBpbnRlcmVzdGluZyBURiAocmV0aW5hIGNlbGwgc3BlY2lmaWNhdGlvbiBhcyB3ZWxsIGFzIGZvcmVicmFpbiBhbmQgZHJvc29waGlsYSBoZWFkL2xpbWIgc3R1ZmZzKQoKIyBTZXNzaW9uIEluZm8KCmBgYHtyfQpkZXZ0b29sczo6c2Vzc2lvbl9pbmZvKCkKYGBgCg==